package com.cskaoyan.config;

import com.cskaoyan.realm.AdminRealm;
import com.cskaoyan.realm.WxRealm;
import org.apache.shiro.cache.CacheManager;
import org.apache.shiro.cache.MemoryConstrainedCacheManager;
import org.apache.shiro.realm.Realm;
import org.apache.shiro.spring.security.interceptor.AuthorizationAttributeSourceAdvisor;
import org.apache.shiro.spring.web.ShiroFilterFactoryBean;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.ArrayList;
import java.util.LinkedHashMap;

/**
 * @Author Gan
 * @Date 2021/7/9 19:38
 * @Description:
 */
@Configuration
public class ShiroConfig {

    @Bean
    public ShiroFilterFactoryBean shiroFilterFactoryBean(DefaultWebSecurityManager securityManager) {
        ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
        shiroFilterFactoryBean.setSecurityManager(securityManager);
//        shiroFilterFactoryBean.setLoginUrl("/unauthc");
        //对请求过滤,key是请求url,value是过滤器
        LinkedHashMap<String, String> filterMap = new LinkedHashMap<>();
        /*  filterMap.put("/admin/auth/login", "anon");
        filterMap.put("/wx/auth/login", "anon");
        filterMap.put("/admin/auth/info", "anon");*/
        //其他的都需要认证才能继续访问
        //filterMap.put("/**", "authc");

        filterMap.put("/**", "anon");

        shiroFilterFactoryBean.setFilterChainDefinitionMap(filterMap);
        return shiroFilterFactoryBean;

    }

    @Bean
    public DefaultWebSecurityManager defaultWebSecurityManager(AdminRealm adminRealm,
                                                               DefaultWebSessionManager sessionManager,
                                                               CustomAuthenticator authenticator,
                                                               WxRealm wxRealm) {
        DefaultWebSecurityManager webSecurityManager = new DefaultWebSecurityManager();
        webSecurityManager.setSessionManager(sessionManager);
        webSecurityManager.setAuthenticator(authenticator);
        ArrayList<Realm> realms = new ArrayList<>();
        realms.add(wxRealm);
        realms.add(adminRealm);
        webSecurityManager.setRealms(realms);
        //不可以两次set会覆盖
        /*webSecurityManager.setRealm(wxRealm);
        webSecurityManager.setRealm(adminRealm);*/
        webSecurityManager.setCacheManager(shiroCacheManager());
        return webSecurityManager;
    }

    @Bean
    public DefaultWebSessionManager webSessionManager() {
        CustomSessionManager customSessionManager = new CustomSessionManager();
        customSessionManager.setGlobalSessionTimeout(System.currentTimeMillis() + 800 * 60 * 60 * 24);
        return customSessionManager;
    }

    /**
     * 声明式权限限定
     * @param securityManager
     * @return
     */
    @Bean
    public AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor(DefaultWebSecurityManager securityManager) {
        AuthorizationAttributeSourceAdvisor authorizationAttributeSourceAdvisor =
                new AuthorizationAttributeSourceAdvisor();
        authorizationAttributeSourceAdvisor.setSecurityManager(securityManager);
        return authorizationAttributeSourceAdvisor;
    }

    @Bean
    public CustomAuthenticator authenticator(AdminRealm adminRealm, WxRealm wxRealm) {
        CustomAuthenticator customAuthenticator = new CustomAuthenticator();
        ArrayList<Realm> realms = new ArrayList<>();
        realms.add(adminRealm);
        realms.add(wxRealm);
        customAuthenticator.setRealms(realms);
        return customAuthenticator;
    }


    /**
     * 配置shiro框架中的CacheManager组件，用于缓存用户权限
     * @return
     */
    @Bean
    public CacheManager shiroCacheManager() {
        return new MemoryConstrainedCacheManager();
    }
}
